﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Wicture.EPC.Service.V1.Filters
{
    public class MoparFilter
    {
        public static readonly string ModelYear = "Y";
        public static readonly string ModelFamily = "F";
        public static readonly string Engine = "E";
        public static readonly string Transmission = "T";
        public static readonly string Line = "L";
        public static readonly string Body = "B";
        public static readonly string Order = "C";
        public static readonly string Trim = "R";
        private List<Dictionary<string, HashSet<string>>> filterList = new List<Dictionary<string, HashSet<string>>>();
        public MoparFilter(string codeReturn)
        {
            filterList = BuildFilterList(codeReturn);
        }
        private List<Dictionary<string, HashSet<string>>> BuildFilterList(string filterStr)
        {
            if (string.IsNullOrEmpty(filterStr)) return new List<Dictionary<string, HashSet<string>>>();
            List<Dictionary<string, HashSet<string>>> dicList = new List<Dictionary<string, HashSet<string>>>();
            var childStrList = filterStr.Split('+');
            foreach (var childStr in childStrList)
            {
                var pairs = childStr.Split('~');
                var pattern1 = pairs[0].Split('^');
                var pattern2 = pairs[1].Split('^');
                Dictionary<string, HashSet<string>> dic = new Dictionary<string, HashSet<string>>();
                for (int i = 0; i < pattern1.Length; i++)
                {
                    if (dic.ContainsKey(pattern1[i]))
                    {
                        dic[pattern1[i]].Add(pattern2[i]);
                    }
                    else
                    {
                        dic.Add(pattern1[i], new HashSet<string> { pattern2[i] });
                    }

                }
                dicList.Add(dic);
            }
            return dicList;
        }
        public static Dictionary<string, string> GetVinFilterOption(dynamic vinInfo)
        {
            Dictionary<string, string> option = new Dictionary<string, string>();
            string modelYear = vinInfo.modelYear;
            string bodyModelCode = vinInfo.bodyModelCode;
            string engineCode = vinInfo.engineCode;
            string transCode = vinInfo.transCode;
            string body = bodyModelCode.Substring(4, 2);
            string family = bodyModelCode.Substring(0, 2);
            string line = bodyModelCode.Substring(2, 1);
            option.Add(ModelYear, modelYear);
            option.Add(Engine, engineCode);
            option.Add(Transmission, transCode);
            //option.Add(Body, body);
            option.Add(ModelFamily, family);
            option.Add(Line, line);
            string featureCodes = vinInfo.featureCodes;
            bool hasTrim = false;
            bool hasOrder = false;
            for (int i = 0; i < featureCodes.Length; i = i + 3)
            {
                string featureCode = featureCodes.Substring(i, 3);
                if (featureCode.StartsWith("-"))
                {
                    option.Add(Order, featureCode);
                    hasOrder = true;
                }
                else if (featureCode.StartsWith("*"))
                {
                    option.Add(Trim, featureCode);
                    hasTrim = true;
                }
                if(hasOrder && hasTrim)
                {
                    break;
                }
            }
            return option;
        }

        public bool IsMath(Dictionary<string, string> option)
        {
            if (option.Count == 0 || filterList.Count == 0)
            {
                return true;
            }
            foreach (var filer in filterList)
            {
                if (MathChild(filer, option))
                {
                    return true;
                }
            }
            return false;
        }

        private bool MathChild(Dictionary<string, HashSet<string>> filter, Dictionary<string, string> option)
        {
            foreach (var key in option.Keys)
            {
                if (filter.ContainsKey(key) && !filter[key].Contains(option[key]))
                {
                    return false;
                }
            }
            return true;
        }
    }
}
